-- reset 8266
if nil == FILE_USER then
    FILE_USER="";
end
timeTable={};
timeIndex=0;
--延时执行
function setTimeout(func,time)
    tmr.alarm(timeIndex,time,0,func);
    if timeIndex < 6 then
        timeIndex=timeIndex+1;
    else
        timeIndex=0;
    end
end
--定时执行
function setInterval(func,time)
    tmr.alarm(timeIndex,time,1,func);
    if timeIndex < 6 then
        timeIndex=timeIndex+1;
    else
        timeIndex=0;
    end
end
sos={
    --重置按键的
    PIN_RESET=8;
    PORT_UDP_DEBUG=9600;
    reset=function()
        if file.exists(FILE_USER) then
            file.remove(FILE_USER);
        end
        wifi.sta.clearconfig();
    end;
    run=function(filename)
        pcall(dofile,{filename});
    end;
    init=function()    
        gpio.mode(sos.PIN_RESET,gpio.INT);
        gpio.trig(sos.PIN_RESET,'both',sos.event.RESET);
        wifi.eventmon.register(wifi.eventmon.STA_CONNECTED,sos.event.STA_CONNECTED);
        wifi.eventmon.register(wifi.eventmon.STA_DISCONNECTED,sos.event.STA_CONNECTED);
        wifi.eventmon.register(wifi.eventmon.STA_AUTHMODE_CHANGE,sos.event.STA_AUTHMODE_CHANGE);
        wifi.eventmon.register(wifi.eventmon.STA_GOT_IP,sos.event.STA_GOT_IP);
        wifi.eventmon.register(wifi.eventmon.STA_DHCP_TIMEOUT,sos.event.STA_DHCP_TIMEOUT);
        wifi.eventmon.register(wifi.eventmon.AP_STACONNECTED,sos.event.AP_STACONNECTED);
        wifi.eventmon.register(wifi.eventmon.AP_STADISCONNECTED,sos.event.AP_STADISCONNECTED);
        wifi.eventmon.register(wifi.eventmon.AP_PROBEREQRECVED,sos.event.AP_PROBEREQRECVED);
        wifi.eventmon.register(wifi.eventmon.WIFI_MODE_CHANGED,sos.event.WIFI_MODE_CHANGED);
        --初始化
        local SSID,PWD = wifi.sta.getconfig();
        if string.len(SSID) > 0 then
            sos.config.SSID = SSID;
            sos.config.PWD = PWD;
            wifi.sta.getap(sos.event.WIFI_GOT_AP);
        else
            print("Start Smart Config");
            wifi.sta.clearconfig();
            sos.wifi_start_smart();
        end
        setInterval(sos.tmr1000,1000);
    end;
    voltage=function()
        if nil ~= adc then
            return adc.readvdd33();
        end
    end;
    tmr1000=function()
        --1s定时逻辑
    end;
    --配置ap模式
    wifi_ap_config=function (ssid,pwd)
        local cfg={
            ssid=ssid,
            pwd=pwd,
            auth=wifi.WPA2_PSK,
            max=1,
            save=false
        };
        wifi.ap.config(cfg);
        wifi.setmode(wifi.SOFTAP);
    end;
    --配置wifi
    wifi_config=function (ssid,pwd)
        wifi.sta.config({ssid=ssid,pwd=pwd,save=true,auto=true});
    end;
    --链接wifi
    wifi_connect=function (ssid,pwd)
        sos.wifi_config(ssid,pwd);
        wifi.sta.connect();
    end;
    --开始智能配网
    wifi_start_smart=function ()
        wifi.setmode(wifi.STATION);
        wifi.startsmart(0,
            function(ssid, password)
                sos.debug("SSID: "..ssid," PWD: "..password);
                wifi.sta.autoconnect(1);
            end
        )
    end;
    udpSocket = net.createUDPSocket();
    udp_send=function(ip,port,data)
        sos.udpSocket:send(port,ip,data);
    end;
    udp_boradcast=function(data)
        sos.udp_send("0.0.0.0",sos.PORT_UDP_DEBUG,data);
    end;
    debug=function(T)
        if(sos.config.debug)then
            sos.udp_boradcast(T);
        end
    end;
    --清除配置文件
    wifi_clean=function ()
        wifi.sta.clearconfig();
    end;
    --成功获取IP
    ready=function(T)
        --发送调试数据
        sos.debug("Wifi Success");
        net.dns.setdnsserver("223.5.5.5",0);
        sos.ws.ws_init();
    end;
    task=function(func,level)
        node.task.post(level,func);
    end;
    config={
        WS="ws://node.sos.top:17420/",
        SSID="",
        PWD="",
        info=node.info(),
        debug=false,
    };
    status={
        reset_key_down=0,
        starting=0x00,
        scan_ap=0x01,
        connecting=0x02,
        connected=0x03,
        ws_connecting=0x04,
        ws_connected=0x05,
        ws_close=0x06,

    };
    --ws连接
    wsl=nil;
    ws={
        ws_status=nil;
        ws_cb={};
        ws_init=function ()
            sos.debug("Start WebSocket");
            sos.wsl = websocket.createClient();
            sos.wsl:config({headers={['User-Agent']='sos'}});
            sos.wsl:on("connection",function(ws)
                sos.ws.ws_status=true;
                sos.ws.ws_login();
                if sos.ws.ws_connect then
                    pcall(sos.ws.ws_connect_cb,{});
                end
            end)
            sos.wsl:on("receive",function(_,msg,opcode)
                sos.debug("WS_REC:"..msg);
                if sos.ws.ws_receive_cb then
                    pcall(sos.ws.ws_receive_cb,{msg});
                end
                local ok,t = pcall(sjson.decode,msg);
                if ok and t then
                    if "userdata" == type(t.i) then
                    else
                        if "nil" == type(sos.ws.ws_cb[ t.t .. t.i ]) then
                            if sos.ws.ws_not_regist_cb then
                                pcall(sos.ws.ws_not_regist_cb,{t.i,t.d,t.t});
                            end
                        else
                            if t.e and string.len(t.e) > 0 then
                                -- 服务器响应失败回调
                                pcall(sos.ws.ws_cb[t.t .. t.i].e,{t.e,t});
                            else
                                -- 服务器响应成功回调
                                pcall(sos.ws.ws_cb[t.t .. t.i].s,{t.d,t});
                            end
                        end
                    end
                else
                    if sos.ws.ws_decode_error_cb then
                        pcall(sos.ws.ws_decode_error_cb,{msg});
                    end;
                end;
            end);
            sos.wsl:on("close",function(_,status)
                sos.debug("Closed:",status);
                sos.wsl=nil;
                setTimeout(sos.ws.ws_init,3000);
            end);
            sos.wsl:connect(sos.config.WS);
        end;
        ws_not_regist_cb=function(i,d,t)
            if sos.server_cb[i] ~= nil then
                pcall(sos.server_cb[i],{d,t});
            end
        end;
        ws_decode_error_cb=function(msg)sos.debug("WS_ERROR:"..msg); end;
        ws_send = function (cmd,content,success,error)
            local t = tmr.now();
            local obj={i=cmd,t=t,d=content};
            local ok, json = pcall(sjson.encode, obj);
            if ok then
                sos.ws.ws_cb[t .. cmd]={s=success,e=error};
                sos.debug(json);
                sos.wsl:send(json);
            else
                if sos.ws.ws_send_cb then
                    pcall(sos.ws.ws_send_cb,{cmd,content});
                end
            end
        end;

        ws_login = function()
            sos.ws.ws_send(
                "login",
                {wifi=wifi.sta.getconfig(),mac=wifi.sta.getmac(),info=node.chipid()},
                function(d)
                    sos.servertime = d.time;
                    sos.timestart = tmr.time();
                    sos.debug("Success Login");
                end,
                sos.ws.ws_err);
        end;
        ws_err=function(err,t)
            sos.debug("Err: " .. err)
        end;
        ws_log=function(msg)
            sos.ws.ws_send("log",{m=msg,t=tmr.time()});
        end;
    };
    server_cb={

    };
    --注册的事件
    event={
        STA_CONNECTED=function(T) end;
        STA_DISCONNECTED=function(T) end;
        STA_AUTHMODE_CHANGE=function(T) end;
        STA_GOT_IP=function(T)local ok,p = pcall(sos.ready,{T});print(ok,p); end;
        STA_DHCP_TIMEOUT=function(T) end;
        AP_STACONNECTED=function(T) end;
        AP_STADISCONNECTED=function(T) end;
        AP_PROBEREQRECVED=function(T) end;
        WIFI_MODE_CHANGED=function(T) end;
        WIFI_GOT_AP=function(t)
            for ssid,v in pairs(t) do
            local authmode, rssi, bssid, channel = string.match(v, "([^,]+),([^,]+),([^,]+),([^,]+)");
            if ssid == sos.config.SSID then
                sos.wifi_connect(sos.config.SSID,sos.config.PWD);
                return ;
            end;
            end;
        end;
        RESET=function(level,pulse)
            if level == gpio.HIGH then
                --按下
                sos.status.reset_key_down=tmr.time();
            else
                local i = tmr.time() - sos.status.reset_key_down;
                if (i)>5 then
                    sos.reset();
                    node.restart();
                elseif i<1 then
                    local majorVer, minorVer, devVer, chipid, flashid, flashsize, flashmode, flashspeed = node.info();
                    sos.udp_boradcast(sjson.encode({majorVar,minorVer,devVer,chipid,flashid,flashsize,flashmode,flashspeed}));
                else
                    if(sos.config.debug)then
                        sos.config.debug=false;
                    else
                        sos.config.debug=true;
                    end;
                end;
                sos.status.reset_key_down=0;
            end;
        end;
    }
}
